<?php
namespace app\controller\model;

use GuzzleHttp\Client;
use think\helper\Str;
use app\BaseController;
class SPay extends BaseController
{
    protected $pri = "";

    protected $pub = "";
    protected $getpath = "";
	public $userID=null;
    protected $mchid = "44507663";
    private $url = "https://mchapi.shengpay.com";
//    private $url = "https://mchapitest.shengpay.com";


    public function __construct()
    {
	    $this->getpath = strtolower(request()->controller()) . "/" . strtolower(request()->action());
        $pri = file_get_contents("../payment/spay_mer.key");
//        exit($pri);
        $pub = file_get_contents("../payment/spay.key");
        $this->pri = "-----BEGIN RSA PRIVATE KEY-----\n" . chunk_split($pri, 64, "\n") . "-----END RSA PRIVATE KEY-----\n";
        $this->pub = "-----BEGIN PUBLIC KEY-----\n" . chunk_split($pub, 64, "\n") . "-----END PUBLIC KEY-----\n";
    }

    public function setSign(array $params): string
    {
        if (empty($this->pri)) throw new \Exception("加签秘钥获取失败");
        // 过滤掉值为空的参数
        $filteredParams = array_filter($params, function ($v, $k) {
            return isset($v) && (!is_string($v) || $v != '');
        }, ARRAY_FILTER_USE_BOTH);

        // 对参数进行排序并连接成一个字符串
        ksort($filteredParams);
        $paramList = array_map(function ($v, $k) {
            return $k . '=' . $v;
        }, $filteredParams, array_keys($filteredParams));
        $content = implode('&', $paramList);
        // 对连接的字符串进行签名
        $sign = '';
        $priKey = openssl_get_privatekey($this->pri);
//        dd($priKey);
        openssl_sign($content, $sign, $this->pri);
//        openssl_free_key($priKey);

        return base64_encode($sign);
    }

    //取消订单
    public function cancelOrder($out_order)
    {
        $config = [
            "mchId" => $this->mchid,
            "outTradeNo" => $out_order,
            "nonceStr" => Str::random(16),
            "signType" => 'RSA',
        ];
        $config['sign'] = $this->setSign($config);
        return $this->send($config, "/pay/reverseOrder");
    }

    //关闭订单
    public function closeOrder($out_order)
    {
        $config = [
            "mchId" => $this->mchid,
            "outTradeNo" => $out_order,
            "nonceStr" => Str::random(16),
            "signType" => 'RSA',
        ];
        $config['sign'] = $this->setSign($config);
        return $this->send($config, "/pay/closeOrder");
    }

    //创建订单
    public function create($type, $orderId, $totalFee, $body, $options, $notify = "")
    {
        $extra = ['appId' => $options['appid']];
        if (!empty($options['openid'])) {
            $extra['openId'] = $options['openid'];
        }
        $data = [
            'mchId' => $this->mchid,
            'outTradeNo' => $orderId,
            'timeExpire' => date("YmdHis", strtotime("+1 hours")),
            'notifyUrl' => $notify,
            'nonceStr' => Str::random(32),
            'totalFee' => (int)bcmul($totalFee, 100),
            'tradeType' => $type, //wx_lite	微信小程序支付
            'extra' => json_encode($extra),
            "body" => $body,
            "currency" => "CNY",
            "clientIp" => request()->ip(),
            "signType" => 'RSA',
            //"isNeedShare" => !empty($options['isNeedShare'])
        ];
        if (!empty($options['isNeedShare'])) $data['isNeedShare'] = "TRUE";
        $data['sign'] = $this->setSign($data);
        return $this->send($data, "/pay/unifiedorderOffline");
    }

    //退款
    public function refund($price, $orderId, $reqId, $desc = '', $notify = '')
    {
        $data = [
            'mchId' => $this->mchid,
            'outTradeNo' => $orderId,
            'outRefundNo' => $reqId,
            'refundFee' => (int)bcmul($price, 100),
            'refundDesc' => $desc,
            'notifyUrl' => $notify,
            'nonceStr' => Str::random(32),
            'signType' => 'RSA'
        ];
        $data['sign'] = $this->setSign($data);
        return $this->send($data, "/refund/orderRefund");
    }

    //订单查询
    public function queryOrder($outOrder)
    {
        $data = [
            "mchId" => $this->mchid,
            "outTradeNo" => $outOrder,
            "nonceStr" => Str::random(32),
            "signType" => 'RSA'
        ];
        $data['sign'] = $this->setSign($data);
        return $this->send($data, "/pay/queryOrder");
    }

    protected function send($_data, $api)
    {
        $client = new Client([
            "base_uri" => $this->url,
            "verify" => false,
            "headers" => ["content-type" => "application/json;charset=utf-8"],
        ]);
        $data = $client->post($api, ['json' => $_data]);
        $items = ($data->getBody()->getContents());
	    w_log($this->userID,"支付","支付下单",$this->getpath);
        $items = json_decode($items, true);
//        dd($items);
        if (empty($items)) echojson([],1,'支付接口返回异常');
        if (strtolower($items['resultCode']) != 'success')  echojson([],1,$items['errorCodeDes']);
        return $items;
    }
}
